import { PackageManagerTabs } from '@theme';

# Migrate from webpack

Rspack's configuration is designed based on webpack, enabling you to migrate your project from webpack to Rspack with ease.

This document is primarily aimed at projects using webpack 5. Since Rspack's API and configuration align with webpack 5.
For projects not using webpack 5, there are other migration guides that can be referenced:

- For projects using webpack v4 or earlier versions, you can refer to [webpack - To v5 from v4](https://webpack.js.org/migrate/5/) to understand the differences.
- For projects using create-react-app or CRACO, you can refer to [Migrating Create React App](/guide/migration/cra).
- For projects using Vue CLI, you can refer to [Rsbuild - Migrating from Vue CLI](https://rsbuild.rs/guide/migration/vue-cli).

## Installing Rspack

In your project directory, install Rspack as a `devDependencies`:

<PackageManagerTabs command="add @rspack/core @rspack/cli -D" />

Now you can remove the webpack-related dependencies from your project:

<PackageManagerTabs command="remove webpack webpack-cli webpack-dev-server" />

:::tip
In some cases, you will still need to keep `webpack` as a dev dependency, such as when using [vue-loader](https://github.com/vuejs/vue-loader).

This is because these packages directly `import` subpaths of webpack and couple with webpack. If you encounter this issue, you can provide feedback to the maintainers of these plugins, asking them if they can make `webpack` an optional dependency.
:::

## Updating package.json

Update your build scripts to use Rspack instead of webpack:

```diff title="package.json"
{
  "scripts": {
-   "serve": "webpack serve",
-   "build": "webpack build",
+   "serve": "rspack serve",
+   "build": "rspack build",
  }
}
```

## Updating configuration

Rename the `webpack.config.js` file to `rspack.config.js`.

:::tip
Rspack commands can specify the configuration file with `-c` or `--config`, similar to webpack commands.
However, unlike webpack, if a configuration file is not explicitly specified, Rspack defaults to using `rspack.config.js`.
:::

Rspack is actively working on implementing webpack's upcoming features, so some configuration defaults differ from webpack 5, as shown below:

| Configuration     | webpack Default | Rspack Default |
| ----------------- | --------------- | -------------- |
| node.global       | true            | 'warn'         |
| node.\_\_filename | 'mock'          | 'warn-mock'    |
| node.\_\_dirname  | 'mock'          | 'warn-mock'    |

You can refer to [Configure Rspack](/config/index) to see the configurations supported by Rspack.

## Webpack built-in plugins

Rspack has implemented most of webpack's built-in plugins, with the same names and configuration parameters, allowing for easy replacement.

For example, replacing the [DefinePlugin](/plugins/webpack/define-plugin):

```diff title="rspack.config.js"
- const webpack = require('webpack');
+ const { rspack } = require('@rspack/core');

module.exports = {
  //...
  plugins: [
-   new webpack.DefinePlugin({
+   new rspack.DefinePlugin({
      // ...
    }),
  ],
}
```

See [Webpack-aligned built-in plugins](/plugins/webpack/index) for more information about supported webpack plugins in Rspack.

## Community plugins

Rspack supports most of the webpack community plugins and also offers alternative solutions for some currently unsupported plugins.

Check [Plugin compat](/guide/compatibility/plugin) for more information on Rspack's compatibility with popular webpack community plugins.

### `copy-webpack-plugin`

Use [rspack.CopyRspackPlugin](/plugins/rspack/copy-rspack-plugin) instead of [copy-webpack-plugin](https://github.com/webpack/copy-webpack-plugin):

```diff title="rspack.config.js"
- const CopyWebpackPlugin = require('copy-webpack-plugin');
+ const { rspack } = require('@rspack/core');

module.exports = {
  plugins: [
-   new CopyWebpackPlugin({
+   new rspack.CopyRspackPlugin({
      // ...
    }),
  ]
}
```

### `mini-css-extract-plugin`

Use [rspack.CssExtractRspackPlugin](/plugins/rspack/css-extract-rspack-plugin) instead of [mini-css-extract-plugin](https://github.com/webpack/mini-css-extract-plugin):

```diff title="rspack.config.js"
- const CssExtractWebpackPlugin = require('mini-css-extract-plugin');
+ const { rspack } = require('@rspack/core');

module.exports = {
  plugins: [
-   new CssExtractWebpackPlugin({
+   new rspack.CssExtractRspackPlugin({
      // ...
    }),
  ]
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
-         CssExtractWebpackPlugin.loader,
+         rspack.CssExtractRspackPlugin.loader,
          "css-loader"
        ],
+       type: 'javascript/auto'
      }
    ]
  }
}
```

### `tsconfig-paths-webpack-plugin`

Use [resolve.tsConfig](/config/resolve#resolvetsconfig) instead of [tsconfig-paths-webpack-plugin](https://github.com/dividab/tsconfig-paths-webpack-plugin):

```diff title="rspack.config.js"
- const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

module.exports = {
  resolve: {
-   plugins: [new TsconfigPathsPlugin({})]
+   tsConfig: {}
  }
}
```

### `fork-ts-checker-webpack-plugin`

Use [ts-checker-rspack-plugin](https://github.com/rspack-contrib/ts-checker-rspack-plugin) instead of [fork-ts-checker-webpack-plugin](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin):

```diff title="rspack.config.js"
- const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
+ const { TsCheckerRspackPlugin } = require('ts-checker-rspack-plugin');

module.exports = {
  plugins: [
-   new ForkTsCheckerWebpackPlugin()
+   new TsCheckerRspackPlugin()
  ]
}
```

## Loaders

Rspack's loader runner is fully compatible with webpack's loader functionality, supporting the vast majority of webpack loaders.
You can use your existing loaders without any changes. However, to achieve the best performance, consider migrating the following loaders:

### [babel-loader](https://github.com/babel/babel-loader) / [swc-loader](https://swc.rs/docs/usage/swc-loader) → builtin:swc-loader

Using `builtin:swc-loader` offers better performance compared to the `babel-loader` and the external `swc-loader`, as it avoids frequent communication between JavaScript and Rust.

If you need custom transformation logic using Babel plugins, you can retain `babel-loader`, but it is recommended to limit its use to fewer files to prevent significant performance degradation.

```diff title="rspack.config.js"
module.exports = {
   module: {
     rules: [
-      {
-        test: /\.tsx?$/i,
-        use: [
-          {
-            loader: 'babel-loader',
-            options: {
-              presets: ['@babel/preset-typescript'],
-            },
-          },
-        ],
-        test: /\.jsx?$/i,
-        use: [
-          {
-            loader: 'babel-loader',
-            options: {
-              presets: ['@babel/preset-react'],
-            },
-          },
-        ],
-      },
+      {
+        test: /\.(j|t)s$/,
+        exclude: [/[\\/]node_modules[\\/]/],
+        loader: 'builtin:swc-loader',
+        options: {
+          jsc: {
+            parser: {
+              syntax: 'typescript',
+            },
+            externalHelpers: true,
+            transform: {
+              react: {
+                runtime: 'automatic',
+                development: !prod,
+                refresh: !prod,
+              },
+            },
+          },
+          env: {
+            targets: 'Chrome >= 48',
+          },
+        },
+      },
+      {
+        test: /\.(j|t)sx$/,
+        loader: 'builtin:swc-loader',
+        exclude: [/[\\/]node_modules[\\/]/],
+        options: {
+          jsc: {
+            parser: {
+              syntax: 'typescript',
+              tsx: true,
+            },
+            transform: {
+              react: {
+                runtime: 'automatic',
+                development: !prod,
+                refresh: !prod,
+              },
+            },
+            externalHelpers: true,
+          },
+          env: {
+            targets: 'Chrome >= 48', // browser compatibility
+          },
+        },
+      },
     ],
   },
 };
```

### [file-loader](https://github.com/webpack-contrib/raw-loader) / [url-loader](https://github.com/webpack-contrib/url-loader) / [raw-loader](https://github.com/webpack-contrib/raw-loader) → [Asset Modules](/guide/features/asset-module)

Rspack implements webpack 5's [Asset Modules](https://webpack.js.org/guides/asset-modules), using asset modules to replace `file-loader`, `url-loader`, and `raw-loader` for better performance.

#### file-loader → asset/resource

```diff title="rspack.config.js"
 module.exports = {
   module: {
     rules: [
-      {
-        test: /\.(png|jpe?g|gif)$/i,
-        use: ["file-loader"],
-      },
+      {
+        test: /\.(png|jpe?g|gif)$/i,
+        type: "asset/resource",
+      },
     ],
   },
 };
```

#### url-loader → asset/inline

```diff title="rspack.config.js"
 module.exports = {
   module: {
     rules: [
-      {
-        test: /\.(png|jpe?g|gif)$/i,
-        use: ["url-loader"],
-      },
+      {
+        test: /\.(png|jpe?g|gif)$/i,
+        type: "asset/inline",
+      },
     ],
   },
 };
```

#### raw-loader → asset/source

```diff title="rspack.config.js"
 module.exports = {
   module: {
     rules: [
-      {
-        test: /^BUILD_ID$/,
-        use: ["raw-loader",],
-      },
+      {
+        test: /^BUILD_ID$/,
+        type: "asset/source",
+      },
     ],
   },
 };
```
